#include <iostream>

#if 0
    // virtual多态（3个函数）
    // 是有代价的，有虚函数指针和虚函数表
    class Animal
    {
    public:
        virtual void speak() = 0;
    };

    class Dog : public Animal
    {
    public:
        void speak()
        {
            std::cout << "汪汪汪\n";
        }
    };

    class Cat : public Animal
    {
    public:
        void speak()
        {
            std::cout << "喵喵喵\n";
        }
    };

    // 多态：用相同的接口传入不同的对象，得到不同的结果
    void Speak(Animal &a)
    {
        a.speak();
    }
#endif

#if 1
    // 奇异递归（6个函数）
    // 运行期多态成本为零，效率很高
    // 但是会让代码膨胀的很大
    template <typename T>
    class Animal
    {
    public:
        void speak()
        {
            // 将自己的对象转成T类型的指针
            ((T *)this)->speak();
        }
    };

    class Dog : public Animal<Dog>
    {
    public:
        void speak()
        {
            std::cout << "汪汪汪\n";
        }
    };

    class Cat : public Animal<Cat>
    {
    public:
        void speak()
        {
            std::cout << "喵喵喵\n";
        }
    };

    // 多态
    template <typename T>
    void Speak(Animal<T> &a)
    {
        a.speak();
    }
#endif

int main()
{
    Dog d;
    Speak(d);
    Cat c;
    Speak(c);

    std::cout << sizeof(d) << std::endl;
    return 0;
}